import _ from 'lodash'
import os from 'os'
import fs from 'fs'
import path from 'path'
import moment from 'moment'
import * as si from 'systeminformation'
import cfg from '../../lib/config/config.js'
import { createRequire } from "module";
const require = createRequire(import.meta.url)
const { exec } = require('node:child_process')

export class stattools extends plugin {
  constructor() {
    super({
      name: 'Tools Status',
      dsc: '设备状态',
      event: 'message',
      rule: [
        {
          reg: '^#st$',
          fnc: 'status'
        }
      ]
    })
  }

async status(e) {

function execSync (cmd) {
  return new Promise((resolve, reject) => {
    exec(cmd, (error, stdout, stderr) => {
      resolve({ error, stdout, stderr })
    })
  })
}

  let shell = null
  if (process.platform == "win32" && !/pro/.test(e.msg)) shell = ""
  let ret = await execSync("bash plugins/tools/Shell/state.sh")
  if (ret.error) {
    e.reply(`请检查是否使用git bash启动Yunzai-bot\n错误信息：${ret.stderr}`)
    shell = ""
  }
  shell = ret.stdout.trim()

function getFileSize (size, isByte = true, isSuffix = true) {
  if (size == null || size == undefined) return 0
  let num = 1024.00 // byte
  if (isByte && size < num) {return size.toFixed(2) + "B"}
  if (size < Math.pow(num, 2)) {return (size / num).toFixed(2) + `K${isSuffix ? "b" : ""}`} // kb
  if (size < Math.pow(num, 3)) {return (size / Math.pow(num, 2)).toFixed(2) + `M${isSuffix ? "b" : ""}`} // M
  if (size < Math.pow(num, 4)) {return (size / Math.pow(num, 3)).toFixed(2) + "G"} // G
  return (size / Math.pow(num, 4)).toFixed(2) + "T" // T
}

function formatTime(time, format, repair = true) {
  const second = parseInt(time % 60)
  const minute = parseInt((time / 60) % 60)
  const hour = parseInt((time / (60 * 60)) % 24)
  const day = parseInt(time / (24 * 60 * 60))
  const timeObj = {
    day,
    hour: repair && hour < 10 ? `0${hour}` : hour,
    minute: repair && minute < 10 ? `0${minute}` : minute,
    second: repair && second < 10 ? `0${second}` : second
  }
  if (format == 'default') {
    let result = ''
    if (day > 0) { result += `${day}天` }
    if (hour > 0) { result += `${timeObj.hour}小时`}
    if (minute > 0) { result += `${timeObj.minute}分` }
    if (second > 0) { result += `${timeObj.second}秒` }
    return result
  }
  if (typeof format === 'string') {
    format = format
      .replace(/dd/g, day)
      .replace(/hh/g, timeObj.hour)
      .replace(/mm/g, timeObj.minute)
      .replace(/ss/g, timeObj.second)
    return format
  }
  if (typeof format === 'function') {
    return format(timeObj)
  }
  return timeObj
}

// 核心
let cores = os.cpus()

// 核心数
let CoreNumber = `${cores.length}`

// 平均/最大频率  使用率
let { currentLoad: { currentLoad }, cpuCurrentSpeed } = await si.get({
      currentLoad: 'currentLoad',
      cpuCurrentSpeed: 'max,avg'
    })

// 使用率
currentLoad = `${currentLoad.toFixed(2)}%`

// 平均
let cpuavg = `${cpuCurrentSpeed.avg}GHz`

// 最大
let cpumax = `${cpuCurrentSpeed.max}GHz`

//内存使用率
let MemUsage = ((1 - os.freemem() / os.totalmem()) * 100).toFixed(2) + "%"

let cpuModel = cores[0]?.model.slice(0, cores[0]?.model.indexOf(" "))

//空闲内存
let freemem = getFileSize(os.freemem())

//内存大小
let totalmem = getFileSize(os.totalmem())

//已用内存
let Usingmemory = getFileSize((os.totalmem() - os.freemem()))

// node
let node = process.memoryUsage()

// 总
let noderss = getFileSize(node.rss)

// 堆
let nodeHT = getFileSize(node.heapTotal)

// 栈
let nodeHU = getFileSize(node.heapUsed)

// node堆栈占用率
let nodeO = ((node.rss / (os.totalmem() - os.freemem())) * 100).toFixed(2) + "%"

// 机器人版本
let name = cfg.package.name
let version = "v" + cfg.package.version

if (name == 'miao-yunzai') {
      name = 'Miao-Yunzai'
    } else if (name == 'yunzai') {
      name = 'Yunzai-Bot'
    } else if (name == 'trss-yunzai') {
      name = 'TRSS-Yunzai'
    } else {
      name = _.capitalize(name)
    }


let botinfo = ''
   let botdata = []
     let BotList = [e.self_id]
    /** TRSS */
    if (Array.isArray(Bot?.uin)) {
      BotList = Bot.uin
    }
    /** ws-plugin、Lain-plugin多bot */
    else if (!Array.isArray(Bot?.uin) && Bot?.adapter && Bot?.adapter.includes(e.self_id)) {
      BotList = Bot.adapter
    }
    for (const i of BotList) {
      const bot = Bot[i]
      if (!bot?.uin) continue
      // 昵称
      const nickname = bot.nickname || "未知"
      // 在线状态
      // 登录平台版本
      const platform = bot.apk ? `${bot.apk.display} v${bot.apk.version}` : bot.version.version || "未知"
      // 收
      const recv = await redis.get(`Yz:count:receive:msg:bot:${bot.uin}:total`) || bot.stat?.recv_msg_cnt
      // 发
      const sent = await redis.get(`Yz:count:send:msg:bot:${bot.uin}:total`) || await redis.get("Yz:count:sendMsg:total")
      // 图
    const screenshot = await redis.get(`Yz:count:send:image:bot:${bot.uin}:total`) || await redis.get("Yz:count:screenshot:total")
      // 好友数
      const friendQuantity = Array.from(bot.fl.values()).length
      // 群数
      const groupQuantity = Array.from(bot.gl.values()).length
      // 本群人数
      const groupMemberQuantity = Array.from(bot.gml?.values() || []).reduce((acc, curr) => acc + curr.size, 0)
      // Bot版本
      const botVersion = bot.version ? `${bot.version.name}(${bot.version.id})${bot.apk ? ` ${bot.version.version}` : ""}` : `ICQQ(QQ) v${require('icqq/package.json').version}`
      const runtime = formatTime(Date.now() / 1000 - bot.stat.start_time, 'dd天hh小时mm分ss秒', false)

     botinfo += `\n - 账号 ${i}`
     botinfo += `\n    * 昵称: ${nickname}`
     botinfo += `\n    * 登录平台: ${botVersion}`
     botinfo += `\n    * 平台版本: ${platform}`
     botinfo += `\n    * 在线时长: ${runtime}`
     botinfo += `\n    * 收: ${recv} | 发: ${sent} | 图: ${screenshot}`
     botinfo += `\n    * 好友: ${friendQuantity} | 群聊: ${groupQuantity} | 本群共 ${groupMemberQuantity} 人`
    }

// 系统运行时长
const systime = await formatTime(os.uptime(), 'dd天hh小时mm分', false)

const runTime = formatTime(moment().diff(moment.unix(this.e.bot.stat.start_time), 'seconds'), 'dd天hh小时mm分', false)

  // 去重
  let HardDisk = _.uniqWith(await si.fsSize(),
    (a, b) =>
      a.used === b.used && a.size === b.size && a.use === b.use && a.available === b.available
  )
    .filter(item => item.size && item.used && item.available && item.use)
  // 数值转换
    let diskinfo = ''
    let i = 0
HardDisk.map(item => {
    item.available = getFileSize(item.available)
    item.used = getFileSize(item.used)
    item.size = getFileSize(item.size)
    item.use = Math.round(item.use)
    diskinfo += `\n - 分区 ${i}`
    diskinfo += `\n    * 分区位置: ${item.fs}`
    diskinfo += `\n    * 文件系统: ${item.type}`
    diskinfo += `\n    * 分区大小: ${item.size}`
    diskinfo += `\n    * 剩余空间: ${item.available}`
    diskinfo += `\n    * 已使用 ${item.used} | ${item.use}%`
    diskinfo += `\n    * 挂载点: ${item.mount}`
    i++
  })

// 系统信息
let osInfo = await si.osInfo()

// 发行名称
let distro = osInfo.distro

  const pluginsDir = './plugins';
  const ignoreDirs = ['system', 'adapter', 'genshin', 'other', 'bin'];
  let _Plugins = ''
  let js = 0
  let plugins = 0

function lsDirScript() {
  const ignoreFiles = ['guoba.support.js', 'index.js', 'main.js'];
  _Plugins += "\n - Scripts:"
  fs.readdirSync(pluginsDir, { withFileTypes: true })
    .filter(dirent => dirent.isDirectory())
    .map(dirent => dirent.name)
    .filter(dir => !ignoreDirs.includes(dir))
    .forEach(dir => {
      const pluginDir = path.join(pluginsDir, dir);
      fs.readdirSync(pluginDir)
        .filter(file => path.extname(file) === '.js' && !ignoreFiles.includes(file))
        .forEach(file => {
          const filePath = path.relative(pluginsDir, path.join(pluginDir, file));
          _Plugins += "\n    * " + filePath
          js++
        });
    });
}

function lsDirPlugin() {
  _Plugins += "\n - Plugins:"
  fs.readdirSync(pluginsDir, { withFileTypes: true })
    .filter(dirent => dirent.isDirectory())
    .map(dirent => dirent.name)
    .filter(dir => !ignoreDirs.includes(dir))
    .forEach(dir => {
      const pluginDir = path.join(pluginsDir, dir);
      const indexFilePath = path.join(pluginDir, 'index.js');
      if (fs.existsSync(indexFilePath)) {
        const filePath = path.relative(pluginsDir, path.dirname(indexFilePath));
         _Plugins += "\n    * " + filePath
         plugins++
      }
    });
}

lsDirScript();
lsDirPlugin();

e.reply(
      "#==CPU=======================" +
      "\n - 核心: " + cpuModel +
      "\n - 核心数: " + CoreNumber +
      "\n - 架构: " + os.arch() +
      "\n - 使用率: " + currentLoad +
      "\n - 平均: " + cpuavg +
      "\n - 最高: " + cpumax +
      "\n#==RAM=======================" +
      "\n - 内存使用率: " + MemUsage +
      "\n - 空闲内存: " + freemem +
      "\n - 内存总大小: " + totalmem +
      "\n - 已用内存: " + Usingmemory +
      "\n#==Disk======================" +
      diskinfo +
      "\n#==Node======================" +
      "\n - 总: " + noderss +
      "\n - 堆: " + nodeHT +
      "\n - 栈: " + nodeHU +
      "\n - 占用率: " + nodeO +
      "\n - 版本号: " + process.version +
      "\n#==Bot=======================" +
      "\n - 版本: " + name + " " + version +
      "\n - 系统: " + distro +
      "\n - 系统运行时长: " + systime +
      "\n - 项目运行时长: " + runTime + botinfo +
      "\n#==Plugin====================" +
      "\n - js插件: " + js + " | 插件包: " + plugins + _Plugins +
      "\n#==System====================" + 
      "\n " + shell
    )
  }
}

logger.info("[tools] 状态(Status) 已加载")